package com.yuw.utils;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.converters.DoubleConverter;
import org.apache.commons.beanutils.converters.LongConverter;

public class MyUtils {

	/**
	 * 将查询结果集转换为List+Bean形式
	 * 
	 * @param <T>
	 *            实体列的Class泛型
	 * 
	 * @param rs
	 *            查询结果集
	 * @return beanlist
	 */
	public static <T> List<T> convertResultSet2BeanList(ResultSet rs, Class<T> clazz) {
		// 返回值
		List<T> lst = new ArrayList<>();
		if (rs != null) {
			try {
				
				// 定义BeanUtils的包装类类型的转换器
				//ConvertUtils.register(new DoubleConverter(), Double.class);
				//ConvertUtils.register(new LongConverter(), Long.class);
				
				// 因为已经遍历过一次结果，所有再次遍历之前，需要将光标移动到最前位置（第一行之前）
				rs.beforeFirst();
				// 获取结果集中的所有的列的信息
				ResultSetMetaData rsmd = rs.getMetaData();
				// 获取结果集中列的个数
				int colCount = rsmd.getColumnCount();
				// 此处应该遍历打印一下列标题
				while (rs.next()) {
					// 创建存储当前行的bean对象
					T tBean = MyUtils.getInstance(clazz);
					// 遍历当前行的每列的信息
					for (int i = 1; i <= colCount; i++) {
						// 取出每一列的列名
						String strColName = rsmd.getColumnLabel(i);
						/*
						 * 注意：需要遵循约定规则：实体类的属性名和数据库的字段名名字要一样，且属性名要全部小写
						 */						
						// 使用apache的第三方工具，来操作实体bean【底层使用了反射】
						Object obj = rs.getObject(strColName);
						BeanUtils.setProperty(tBean, strColName.toLowerCase(), obj);						
					}
					// 将当前行的实体对象存入list中
					lst.add(tBean);
				}

			} catch (Exception e) {
				// 将查询结果集转换为List对象异常：
				System.out.println("将查询结果集转换为List对象异常：" + e.getMessage());
				e.printStackTrace();
			}
		}

		return lst;

	}
	
	/**
	 * 将查询结果集转何为List
	 * 
	 * @param rs
	 *            查询结果集
	 * @return List结果
	 */
	public static List<Map<String, Object>> convertResultSet2List(ResultSet rs) {
		List<Map<String, Object>> lst = new ArrayList<>();
		if (rs != null) {
			try {
				// 因为已经遍历过一次结果，所有再次遍历之前，需要将光标移动到最前位置（第一行之前）
				rs.beforeFirst();
				// 获取结果集中的所有的列的信息
				ResultSetMetaData rsmd = rs.getMetaData();
				// 获取结果集中列的个数
				int colCount = rsmd.getColumnCount();
				// 此处应该遍历打印一下列标题
				while (rs.next()) {
					// 创建存储当前行的map对象【有序】
					Map<String, Object> mapRow = new LinkedHashMap<>();
					// 遍历当前行的每列的信息
					for (int i = 1; i <= colCount; i++) {
						// 取出每一列的列名
						String strColName = rsmd.getColumnLabel(i);
						// 通过列名获取当前行当前列的值
						// 将当前类的值存入map中
						mapRow.put(strColName, rs.getObject(strColName));
					}
					// 将当前行的map存入list中
					lst.add(mapRow);
				}
			} catch (SQLException e) {
				// 将查询结果集转换为List对象异常：
				System.out.println("将查询结果集转换为List对象异常：" + e.getMessage());
				e.printStackTrace();
			}
		}
		return lst;
	}

	/**
	 * 简单工厂模式：获取一个指定Class的实例对象
	 * 
	 * @param clazz
	 *            Class
	 * @return 实例对象
	 */
	public static <T> T getInstance(Class<T> clazz) {
		// 返回值
		T t = null;
		try {
			// 反射获取该Class的一个实例对象
			t = clazz.newInstance();
		} catch (Exception e) {
			// 获取实例对象异常
			System.out.println("获取实例对象异常:" + e.getMessage());
			e.printStackTrace();
		}
		return t;
	}
}
